package dbutil

import (
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

// Helper 将gorm.Migrator转换为链式调用，方便数据库migrate调用
type Helper struct {
	m   gorm.Migrator
	err error
}

func (h *Helper) Error() error {
	return h.err
}

func With(db *gorm.DB) *Helper {
	return &Helper{m: db.Migrator()}
}

func (h *Helper) CreateTable(dst ...interface{}) *Helper {
	for _, v := range dst {
		if h.err == nil && !h.m.HasTable(v) {
			h.err = h.m.CreateTable(v)
		}
	}
	return h
}

func (h *Helper) DropTable(dst ...interface{}) *Helper {
	for _, v := range dst {
		if h.err == nil && h.m.HasTable(v) {
			h.err = h.m.DropTable(v)
		}
	}
	return h
}

func (h *Helper) RenameTable(oldName, newName interface{}) *Helper {
	if h.err == nil {
		h.err = h.m.RenameTable(oldName, newName)
	}
	return h
}

func (h *Helper) AddColumn(dst interface{}, fieldOption ...string) *Helper {
	for _, field := range fieldOption {
		if h.err != nil {
			return h
		} else {
			h.err = h.m.AddColumn(dst, field)
		}
	}
	return h
}

func (h *Helper) DropColumn(dst interface{}, fieldOption ...string) *Helper {
	for _, field := range fieldOption {
		if h.err != nil {
			return h
		} else {
			h.err = h.m.DropColumn(dst, field)
		}
	}
	return h
}

func (h *Helper) AlterColumn(dst interface{}, field string) *Helper {
	if h.err == nil {
		h.err = h.m.AlterColumn(dst, field)
	}
	return h
}

func (h *Helper) MigrateColumn(dst interface{}, field *schema.Field, columnType gorm.ColumnType) *Helper {
	if h.err == nil {
		h.err = h.m.MigrateColumn(dst, field, columnType)
	}
	return h
}

func (h *Helper) RenameColumn(dst interface{}, oldName, field string) *Helper {
	if h.err == nil {
		h.err = h.m.RenameColumn(dst, oldName, field)
	}
	return h
}

func (h *Helper) CreateView(name string, option gorm.ViewOption) *Helper {
	if h.err == nil {
		h.err = h.m.CreateView(name, option)
	}
	return h
}

func (h *Helper) DropView(name string) *Helper {
	if h.err == nil {
		h.err = h.m.DropView(name)
	}
	return h
}

func (h *Helper) CreateConstraint(dst interface{}, name string) *Helper {
	if h.err == nil {
		h.err = h.m.CreateConstraint(dst, name)
	}
	return h
}

func (h *Helper) DropConstraint(dst interface{}, name string) *Helper {
	if h.err == nil {
		h.err = h.m.DropConstraint(dst, name)
	}
	return h
}

func (h *Helper) CreateIndex(dst interface{}, name string) *Helper {
	if h.err == nil {
		h.err = h.m.CreateIndex(dst, name)
	}
	return h
}

func (h *Helper) DropIndex(dst interface{}, name string) *Helper {
	if h.err == nil {
		h.err = h.m.DropIndex(dst, name)
	}
	return h
}

func (h *Helper) RenameIndex(dst interface{}, oldName, newName string) *Helper {
	if h.err == nil {
		h.err = h.m.RenameIndex(dst, oldName, newName)
	}
	return h
}
